import os, sys
from tkinter import *
from tkinter import filedialog, dialog
from threading import Thread
import pygame
import random
import queue
import math
import time

def resource_path(relative):
    if hasattr(sys, "_MEIPASS"):
        absolute_path = os.path.join(sys._MEIPASS, relative)
    else:
        absolute_path = os.path.join(relative)
    return absolute_path

CODETITLE = 'Ataxx'
WIDTH = 480
INFOBOXHIGHT = 120
HIGHT = WIDTH+INFOBOXHIGHT
CHECKSIZE = 67.5
FPS = 24
INF = int(1e5)
EMPTYID = 0
BLACKID = 1
WHITEID = 2
EASYAIDELAY = FPS//2
AIMOVEDELAY = FPS*3//4
DPDELAY = FPS
hintarea0 = ((0,1),(1,1),(1,0),(0,-1),(-1,-1),(-1,0),(-1,1),(1,-1))
hintarea1 = ((0,2),(2,2),(2,0),(0,-2),(-2,-2),(-2,0),(-2,2),(2,-2),(1,2),(1,-2),(-1,2),(-1,-2),(2,-1),(2,1),(-2,-1),(-2,1))
infohight = 20
buttonhight = 70
hintimage = [None,None]
pieceimage = [[None,None,None,None],[None,None,None,None]]
buttonimage = [None,None,None]
minibtimage = [None,None,None,None]
playerimage = [None,None,None]
buttonlist = [['开始','设置','悔棋','认输'],['播放',' 1x ','上一步','下一步','导入','导出']]
alpha0 = 245
mousepos = (0,0)
useai = [0,0]
quitgame = False
gameover = True
boardmap = [[0 for j in range(7)] for i in range(7)]
aimap = [[0 for j in range(7)] for i in range(7)]
pof = [0 for i in range(10)]
history = []
piecenums = [0,0]
hintlist = [[],[]]
wantpiece = None
tmppiece = None
playerid = 0
steps = 0
allowwithdraw = True
beginstate = 0
settingstate = 0
withdrawstate = 2
giveupstate = 2
updownstate = 0
importstate = 0
exportstate = 0
playbackstate = 2
speedstate = 2
displayok = False
displaying = False
dpspeed = 1
dpdelay = 0
dpok = False
aiok = False
aistart = False
aiworking = 0
aidelay = 0
warntext = ''
warnalpha = 0
maxdepth = 0
uptext = '  同  化  棋'
class move():
    def __init__(self):
        self.p = 0
        self.f = [0,0]
        self.df = False
        self.t = [0,0]
        self.th = []

def drawtext(text, size, color, pos):
    myfont = pygame.font.Font(resource_path('simsun.ttc'), size)
#    pygame.font.Font.set_bold(myfont, True)
    textImage = myfont.render(text, True, color)
    window.blit(textImage, pos)
def drawnumber(text, pos):
    myfont = pygame.font.Font(resource_path('LESLIEB.TTF'), 36)
    pygame.draw.rect(window, (100,0,0), (pos[0]-4, pos[1]-2, 50, 40), 1)
    textImage = myfont.render(text, True, (200,0,0))
    window.blit(textImage, pos)
def warnbox(text,alpha):
    temp = pygame.Surface((280,30)).convert()
    temp.fill((200,255,255))
    myfont = pygame.font.Font(resource_path('simsun.ttc'), 20)
    textImage = myfont.render(text, True, (0,0,0))
    temp.blit(textImage, (10,5))
    temp.set_alpha(int(alpha))
    window.blit(temp,(100,INFOBOXHIGHT))
def drawbutton(text, pos, state):
    window.blit(buttonimage[state], pos)
    if state == 2:
        drawtext(text, 24, (120,120,120), (pos[0]+18,pos[1]+8))
    else:
        drawtext(text, 24, (0,0,0), (pos[0]+18,pos[1]+7))
    return
def getpos():
    mpos = list(pygame.mouse.get_pos())
    if mpos[1] < INFOBOXHIGHT:
        if mpos[0]>10 and mpos[0]<95 and mpos[1]>buttonhight and mpos[1]<buttonhight+40:
            return (-1,0)
        elif mpos[0]>116 and mpos[0]<201 and mpos[1]>buttonhight and mpos[1]<buttonhight+40:
            return (-1,1)
        elif mpos[0]>222 and mpos[0]<307 and mpos[1]>buttonhight and mpos[1]<buttonhight+40:
            return (-1,2)
        elif mpos[0]>328 and mpos[0]<413 and mpos[1]>buttonhight and mpos[1]<buttonhight+40:
            return (-1,3)
        elif mpos[0]>428 and mpos[0]<463 and mpos[1]>buttonhight+2 and mpos[1]<buttonhight+39:
            return (-1,4)
        else:
            return None
    else:
        mpos[1] -= INFOBOXHIGHT
        if mpos[0]%CHECKSIZE < 7.5 or mpos[1]%CHECKSIZE < 7.5:
            return None
        else:
            return [int(mpos[0]/CHECKSIZE), int(mpos[1]/CHECKSIZE)]
def show():
    window.blit(backgroundimage, (0,0))
    window.blit(infoboximage, (0,0))
    window.blit(boardimage, (0,INFOBOXHIGHT))
    if updownstate & 2:
        drawbutton('导入',(10,buttonhight),importstate)
        drawbutton('导出',(116,buttonhight),exportstate)
        if displaying:
            drawbutton('暂停',(222,buttonhight),playbackstate)
        else:
            drawbutton('播放',(222,buttonhight),playbackstate)
        if dpspeed > 0:
            drawbutton(' %dx '%(1<<(dpspeed-1)),(328,buttonhight),speedstate)
        else:
            drawbutton('0.5x',(328,buttonhight),speedstate)
    else:
        drawbutton('开始',(10,buttonhight),beginstate)
        drawbutton('设置',(116,buttonhight),settingstate)
        drawbutton('悔棋',(222,buttonhight),withdrawstate)
        drawbutton('认输',(328,buttonhight),giveupstate)
    window.blit(minibtimage[updownstate], (428,buttonhight+2))
    if playerid == 1:
        drawtext('黑方下棋',36,(0,0,0),(170,infohight))
    elif playerid == 2:
        drawtext('白方下棋',36,(0,0,0),(170,infohight))
    else:
        drawtext(uptext,30,(0,0,0),(135,infohight))
    drawnumber('%02d'%piecenums[0], (22,infohight))
    drawnumber('%02d'%piecenums[1], (416,infohight))
    window.blit(playerimage[useai[0]],(80,infohight-3))
    window.blit(playerimage[useai[1]],(370,infohight-3))
    for t in hintlist[0]:
        window.blit(hintimage[0], (int(t[0]*CHECKSIZE),int(t[1]*CHECKSIZE)+INFOBOXHIGHT))
    for t in hintlist[1]:
        window.blit(hintimage[1], (int(t[0]*CHECKSIZE),int(t[1]*CHECKSIZE)+INFOBOXHIGHT))
    for i in range(7):
        for j in range(7):
            if boardmap[i][j]:
                window.blit(pieceimage[(boardmap[i][j]&3)-1][0], (int(i*CHECKSIZE+7.5),int(j*CHECKSIZE+7.5)+INFOBOXHIGHT))
    if wantpiece:
        if boardmap[wantpiece[0]][wantpiece[1]]:
            window.blit(pieceimage[playerid-1][3], (int(wantpiece[0]*CHECKSIZE+7.5),int(wantpiece[1]*CHECKSIZE+7.5)+INFOBOXHIGHT))
        else:
            window.blit(pieceimage[playerid-1][1], (int(wantpiece[0]*CHECKSIZE+7.5),int(wantpiece[1]*CHECKSIZE+7.5)+INFOBOXHIGHT))
    if tmppiece:
        window.blit(pieceimage[playerid-1][2], (int(tmppiece[0]*CHECKSIZE+7.5),int(tmppiece[1]*CHECKSIZE+7.5)+INFOBOXHIGHT))

    if warnalpha:
        warnbox(warntext,warnalpha)
def okay(tmp, wnt):
    if boardmap[wnt[0]][wnt[1]]:
        return False
    if max(abs(tmp[0]-wnt[0]), abs(tmp[1]-wnt[1])) > 2:
        return False
    return True
def mouseproc(mx, my):
    global wantpiece,beginstate,settingstate,withdrawstate,giveupstate,updownstate,importstate,exportstate,playbackstate,speedstate
    beginstate &= 2
    settingstate &= 2
    withdrawstate &= 2
    giveupstate &= 2
    updownstate &= 2
    importstate &= 2
    exportstate &= 2
    playbackstate &= 2
    speedstate &= 2
    if not aiworking and not displayok:
        wantpiece = None
    if mx < 0:
        if updownstate&2:
            if my == 0:
                if importstate == 0:
                    importstate = 1
            elif my == 1:
                if exportstate == 0:
                    exportstate = 1
            elif my == 2:
                if playbackstate == 0:
                    playbackstate = 1
            elif my == 3:
                if speedstate == 0:
                    speedstate = 1
            elif my == 4:
                updownstate |= 1
        else:
            if my == 0:
                if beginstate == 0:
                    beginstate = 1
            elif my == 1:
                if settingstate == 0:
                    settingstate = 1
            elif my == 2:
                if withdrawstate == 0:
                    withdrawstate = 1
            elif my == 3:
                if giveupstate == 0:
                    giveupstate = 1
            elif my == 4:
                updownstate |= 1
    elif not aiworking and not gameover and not displayok:
        if tmppiece and okay(tmppiece,(mx, my)):
            wantpiece = (mx, my)
        elif playerid and boardmap[mx][my] == playerid:
            wantpiece = (mx, my)
def judge():
    for i in range(7):
        for j in range(7):
            if boardmap[i][j] == playerid:
                for t in hintarea0:
                    if t[0]+i>=0 and t[1]+j>=0 and t[0]+i<7 and t[1]+j<7 and not boardmap[t[0]+i][t[1]+j]:
                        return False
                for t in hintarea1:
                    if t[0]+i>=0 and t[1]+j>=0 and t[0]+i<7 and t[1]+j<7 and not boardmap[t[0]+i][t[1]+j]:
                        return False
    return True
def withdraw():
    global steps,boardmap,history,playerid,hintlist,tmppiece,wantpiece,warntext,warnalpha,piecenums,aiworking,aiok,\
        beginstate,settingstate,giveupstate,gameover,dpok,dpdelay,displaying
    if steps > 0:
        steps -= 1
        playerid = history[steps].p
        tmp = history[steps].f
        boardmap[history[steps].f[0]][history[steps].f[1]] = playerid
        boardmap[history[steps].t[0]][history[steps].t[1]] = EMPTYID
        if not history[steps].df:
            piecenums[playerid-1] -= 1
        for t in history[steps].th:
            boardmap[t[0]][t[1]] = playerid^3
            piecenums[playerid-1] -= 1
            piecenums[(playerid^3)-1] += 1
        history.pop()
        hintlist = [[],[]]
        beginstate = 2;giveupstate = 0
        tmppiece = None;wantpiece = None
        aiworking = useai[playerid-1]
        aiok = False
        gameover = False
        dpok = False
        dpdelay = DPDELAY/(1<<dpspeed)
        displaying = False
    else:
        warntext = '      没有棋可以悔了'
        warnalpha = alpha0
def procinfo():
    global warnalpha
    if warnalpha:
        if warnalpha > alpha0:
            warnalpha -= 1
        else:
            warnalpha = max(0, 1.1*warnalpha-25.5)
    return
def getmouse():
    global wantpiece,tmppiece,hintlist,playerid,boardmap,gameover,history,steps,piecenums,uptext,aiworking,aiok,warntext,warnalpha,\
           beginstate,settingstate,withdrawstate,giveupstate,updownstate,importstate,exportstate,playbackstate,speedstate,displaying,\
           dpspeed,dpok
    if beginstate == 1:
        boardinit()
    elif settingstate == 1:
        setwindow()
    elif withdrawstate == 1:
        withdraw()
        withdraw()
    elif giveupstate == 1:
        gameover = True
        if playerid == 1:
            uptext = '   黑方认输'
        else:
            uptext = '   白方认输'
        playerid = 0;dpok = False;displaying = False
        beginstate = 0;withdrawstate = 2;giveupstate = 2
    elif updownstate&1:
        updownstate ^= 2
    elif importstate == 1:
        importmap()
    elif exportstate == 1:
        exportmap()
    elif playbackstate == 1:
        displaying = not displaying
    elif speedstate == 1:
        dpspeed += 1
        dpspeed &= 3
    if not gameover and not aiworking and not displayok:
        if wantpiece:
            if tmppiece and wantpiece == tmppiece:
                hintlist = [[],[]]
                tmppiece = None
            elif boardmap[wantpiece[0]][wantpiece[1]]:
                tmppiece = wantpiece
                hintlist = [[],[]]
                for t in hintarea0:
                    tmpx = t[0]+wantpiece[0]; tmpy = t[1]+wantpiece[1]
                    if tmpx>=0 and tmpy>=0 and tmpx<7 and tmpy<7 and not boardmap[tmpx][tmpy]:
                        hintlist[0].append((tmpx, tmpy))
                for t in hintarea1:
                    tmpx = t[0]+wantpiece[0]; tmpy = t[1]+wantpiece[1]
                    if tmpx>=0 and tmpy>=0 and tmpx<7 and tmpy<7 and not boardmap[tmpx][tmpy]:
                        hintlist[1].append((tmpx, tmpy))
            else:
                makemove()
        elif tmppiece:
            if mousepos and mousepos[0] >= 0:
                if boardmap[mousepos[0]][mousepos[1]]:
                    warntext = '移动不合法：此处已有棋子'
                    warnalpha = alpha0
                else:
                    warntext = '移动不合法：超出可移动范围'
                    warnalpha = alpha0
        elif mousepos and mousepos[0] >= 0:
            if boardmap[mousepos[0]][mousepos[1]] and not gameover:
                warntext = '选择不合法：请选择己方棋子'
                warnalpha = alpha0
def makemove():
    global gameover,history,boardmap,piecenums,playerid,steps,hintlist,tmppiece,wantpiece,aiworking,aidelay,aiok,uptext,warntext,\
            beginstate,settingstate,withdrawstate,giveupstate,importstate,exportstate,displaying
    history.append(move())
    history[steps].p = playerid
    history[steps].f = tmppiece
    history[steps].t = wantpiece
    boardmap[wantpiece[0]][wantpiece[1]] = playerid
    piecenums[playerid-1] += 1
    if max(abs(tmppiece[0]-wantpiece[0]), abs(tmppiece[1]-wantpiece[1])) == 2:
        boardmap[tmppiece[0]][tmppiece[1]] = 0
        piecenums[playerid-1] -= 1
        history[steps].df = True
    for t in hintarea0:
        tmpx = t[0]+wantpiece[0]; tmpy = t[1]+wantpiece[1]
        if tmpx>=0 and tmpy>=0 and tmpx<7 and tmpy<7 and boardmap[tmpx][tmpy] == playerid^3:
            boardmap[tmpx][tmpy] = playerid
            piecenums[playerid-1] += 1
            piecenums[(playerid^3)-1] -= 1
            history[steps].th.append((tmpx,t[1]+wantpiece[1]))
    steps += 1
    playerid = playerid^3
    hintlist = [[],[]]
    tmppiece = None
    wantpiece = None
    aiok = False
    aiworking = useai[playerid-1]
    if aiworking == 1:
        aidelay = EASYAIDELAY
        giveupstate = 2
    elif aiworking == 2:
        aidelay = 0
        giveupstate = 2
    else:
        giveupstate = 0
    if judge():
        gameover = True
        finalnums = piecenums[:]
        finalnums[(playerid^3)-1] = 49-finalnums[playerid-1]
        if finalnums[0] > finalnums[1]:
            uptext = '黑{0:02d}:白{1:02d},黑胜'.format(*finalnums)
        else:
            uptext = '黑{0:02d}:白{1:02d},白胜'.format(*finalnums)
        displaying = False
        playerid = 0; beginstate = 0; giveupstate = 2
def boardinit():
    global pof,boardmap,history,hintlist,hintimage,pieceimage,wantpiece,tmppiece,playerid,steps,gameover,piecenums,displayok,displaying,\
        beginstate,settingstate,withdrawstate,giveupstate,aiworking,aiok,aistart,importstate,exportstate,playbackstate,speedstate
    gameover = False
    boardmap = [[0 for j in range(7)] for i in range(7)]
    history = []
    hintlist = [[],[]]
    wantpiece = None
    tmppiece = None
    playerid = 1
    steps = 0
    beginstate = 2
    pof[0] = INF
    aiworking = useai[0]
    aiok = False
    aistart = False
    if allowwithdraw:
        withdrawstate = 0
    if not aiworking:
        giveupstate = 0
    #importstate = 2
    #exportstate = 2
    playbackstate = 2
    speedstate = 2
    displayok = False
    displaying = False
    boardmap[0][0] = boardmap[6][6] = BLACKID
    boardmap[0][6] = boardmap[6][0] = WHITEID
    piecenums = [2, 2]
def maxmatrix(plr):
    l = [[i for i in range(7)] for j in range(7)]
    r = [[i for i in range(7)] for j in range(7)]
    h = [[1 for i in range(7)] for j in range(7)]
    maxsum = 0
    for i in range(7):
        for j in range(1,7):
            if aimap[i][j] == plr and aimap[i][j-1] == plr:
                l[i][j] = l[i][j-1]
    for i in range(7):
        for j in range(5,-1,-1):
            if aimap[i][j] == plr and aimap[i][j+1] == plr:
                r[i][j] = r[i][j+1]
    for i in range(7):
        for j in range(7):
            if i > 0 and aimap[i][j] == plr and aimap[i-1][j] == plr:
                r[i][j]=min(r[i][j],r[i-1][j])
                l[i][j]=max(l[i][j],l[i-1][j])
                h[i][j] = h[i-1][j]+1
            maxsum = max(maxsum, (r[i][j]-l[i][j]+1)*h[i][j])
    return maxsum
def cntdec(plr):
    tmppoint = 0
    for i in range(7):
        for j in range(7):
            if aimap[i][j] == plr:
                tmppoint += 1
            elif boardmap[i][j] == plr^3:
                tmppoint -= 1
    return tmppoint
def aisearch(dep, plr):
    global aimap, pof
    if dep > maxdepth:
        return 200*cntdec(playerid)+maxmatrix(playerid)**2-maxmatrix(playerid^3)**2
    tmpmove = move()
    bestmove = None
    for i in range(7):
        for j in range(7):
            if not aimap[i][j]:
                for t in hintarea0:
                    if t[0]+i>=0 and t[1]+j>=0 and t[0]+i<7 and t[1]+j<7 and aimap[t[0]+i][t[1]+j] == plr:
                        tmpmove.f = (t[0]+i,t[1]+j)
                        tmpmove.df = False
                        tmpmove.t = (i,j)
                        if dep == 1 and not bestmove:
                            bestmove = (tmpmove.f,tmpmove.t)
                        aimap[i][j] = plr
                        for tt in hintarea0:
                            if tt[0]+i>=0 and tt[1]+j>=0 and tt[0]+i<7 and tt[1]+j<7 and aimap[tt[0]+i][tt[1]+j] == plr^3:
                                aimap[tt[0]+i][tt[1]+j] = plr
                                tmpmove.th.append((tt[0]+i,tt[1]+j))
                        if dep&1:
                            pof[dep+1]=INF
                            tmp = aisearch(dep+1, plr^3)
                            if tmp > pof[dep]:
                                pof[dep] = tmp
                                if dep == 1:
                                    bestmove = (tmpmove.f,tmpmove.t)
                            if pof[dep] > pof[dep-1]:
                                aimap[t[0]+i][t[1]+j] = plr
                                aimap[i][j] = EMPTYID
                                for tt in tmpmove.th:
                                    aimap[tt[0]][tt[1]] = plr^3
                                return pof[dep]
                        else:
                            pof[dep+1]=-INF
                            pof[dep] = min(pof[dep],aisearch(dep+1, plr^3))
                            if pof[dep] < pof[dep-1]:
                                aimap[t[0]+i][t[1]+j] = plr
                                aimap[i][j] = EMPTYID
                                for tt in tmpmove.th:
                                    aimap[tt[0]][tt[1]] = plr^3
                                return pof[dep]
                        aimap[i][j] = EMPTYID
                        for tt in tmpmove.th:
                            aimap[tt[0]][tt[1]] = plr^3
                        break
                for t in hintarea1:
                    if t[0]+i>=0 and t[1]+j>=0 and t[0]+i<7 and t[1]+j<7 and aimap[t[0]+i][t[1]+j] == plr:
                        tmpmove.f = (t[0]+i,t[1]+j)
                        tmpmove.df = True
                        tmpmove.t = (i,j)
                        if dep == 1 and not bestmove:
                            bestmove = (tmpmove.f,tmpmove.t)
                        aimap[t[0]+i][t[1]+j] = EMPTYID
                        aimap[i][j] = plr
                        for tt in hintarea0:
                            if tt[0]+i>=0 and tt[1]+j>=0 and tt[0]+i<7 and tt[1]+j<7 and aimap[tt[0]+i][tt[1]+j] == plr^3:
                                aimap[tt[0]+i][tt[1]+j] = plr
                                tmpmove.th.append((tt[0]+i,tt[1]+j))
                        if dep&1:
                            pof[dep+1]=INF
                            tmp = aisearch(dep+1, plr^3)
                            if tmp > pof[dep]:
                                pof[dep] = tmp
                                if dep == 1:
                                    bestmove = (tmpmove.f,tmpmove.t)
                            if pof[dep] > pof[dep-1]:
                                aimap[t[0]+i][t[1]+j] = plr
                                aimap[i][j] = EMPTYID
                                for tt in tmpmove.th:
                                    aimap[tt[0]][tt[1]] = plr^3
                                return pof[dep]
                        else:
                            pof[dep+1]=-INF
                            pof[dep] = min(pof[dep],aisearch(dep+1, plr^3))
                            if pof[dep] < pof[dep-1]:
                                aimap[t[0]+i][t[1]+j] = plr
                                aimap[i][j] = EMPTYID
                                for tt in tmpmove.th:
                                    aimap[tt[0]][tt[1]] = plr^3
                                return pof[dep]
                        aimap[t[0]+i][t[1]+j] = plr
                        aimap[i][j] = EMPTYID
                        for tt in tmpmove.th:
                            aimap[tt[0]][tt[1]] = plr^3
    if dep == 1:
        return bestmove
    return pof[dep]
def aiwork():
    global aiok, aidelay, pof, maxdepth, aistart, aimap, tmppiece, wantpiece
    maxdepth = aiworking|1
    pof[1] = -INF
    aimap = [t[:] for t in boardmap]
    tmp = aisearch(1, playerid)
    if aiworking:
        tmppiece = tmp[0]
        wantpiece = tmp[1]
        aidelay = AIMOVEDELAY
        aiok = True
    aistart = False
def setok():
    global useai, allowwithdraw
    useai[0] = v1.get()
    useai[1] = v2.get()
    allowwithdraw = v3.get()
    if useai[0] and useai[1]:
        allowwithdraw = False
    setwin.destroy()
def setcancel():
    setwin.destroy()
def setwindow():
    global setwin, v1, v2, v3
    setwin = Tk()
    setwin.iconbitmap(resource_path('ataxx.ico'))
    setwin.title("设置")
    setwin.geometry("240x260")
    setwin.resizable(False, False)
    setwin.wm_attributes('-topmost',1)
    LANGS=[('玩家   ',0),('简单ai  ',1),('困难ai  ',2)]
    group1 = LabelFrame(setwin,text="黑方：",padx=5,pady=5)
    group1.pack(side=TOP,padx=10,pady=10)
    v1 = IntVar()
    v1.set(useai[0])
    for long,num in LANGS:
        b1 = Radiobutton(group1,text=long,variable=v1,value=num)
        b1.pack(side=LEFT)
    group2 = LabelFrame(setwin,text="白方：",padx=5,pady=5)
    group2.pack(side=TOP,padx=10,pady=0)
    v2 = IntVar()
    v2.set(useai[1])
    for long,num in LANGS:
        b2 = Radiobutton(group2,text=long,variable=v2,value=num)
        b2.pack(side=LEFT)
    group3 = LabelFrame(setwin,text="悔棋设置：",padx=5,pady=5)
    group3.pack(side=TOP,padx=10,pady=10)
    LANGS1=[('允许   ',True),('禁止                      ',False)]
    v3 = BooleanVar()
    v3.set(allowwithdraw)
    for long,num in LANGS1:
        b3 = Radiobutton(group3,text=long,variable=v3,value=num)
        b3.pack(side=LEFT)
    cancel_button=Button(setwin, text='取消', command = lambda:setcancel())
    cancel_button.pack(side=RIGHT,padx=20,ipadx=20)
    ok_button=Button(setwin, text='确定', command = lambda:setok())
    ok_button.pack(side=LEFT,padx=20,ipadx=20)
    mainloop()
def importmap():
    global importtext,warnalpha,warntext,dpstep,playbackstate,speedstate,displayok,useai,dpdelay,dpok,dpspeed
    tmpwin = Tk()
    tmpwin.withdraw()
    tmpwin.iconbitmap(resource_path('ataxx.ico'))
    file_path = filedialog.askopenfilename(title=u'导入棋谱',filetypes=[("Ataxx", ".ata")])
    if file_path:
        f = open(file_path, mode='r')
        if f.readline().strip('\n') == '#Designed By Kevin':
            importtext=[t.split() for t in f.readlines()]
            dpstep = len(importtext)
            useai = [0,0]
            boardinit()
            playbackstate = 0
            speedstate = 0
            displayok = True
            dpdelay = 0
            dpok = False
            dpspeed = 1
            warntext = '         导入成功'
            warnalpha = alpha0
        else:
            warntext = '    导入文件格式不正确'
            warnalpha = 255
    tmpwin.destroy()
def exportmap():
    global warnalpha,warntext
    if steps:
        tmpwin = Tk()
        tmpwin.withdraw()
        tmpwin.iconbitmap(resource_path('ataxx.ico'))
        file_path = filedialog.asksaveasfilename(title=u'导出棋谱',filetypes=[("Ataxx", ".ata")],defaultextension='.ata')
        if file_path:
            f = open(file_path, mode='w')
            text = '#Designed By Kevin\n'
            for tmp in history:
                text += ' '.join([str(tmp.f[0]),str(tmp.f[1]),str(tmp.t[0]),str(tmp.t[1])])+'\n'
            f.write(text)
            f.close()
            warntext = '         导出成功'
            warnalpha = 255
        tmpwin.destroy()
    else:
        warntext = '     没有棋谱可以导出'
        warnalpha = alpha0
def loadimages():
    global backgroundimage,infoboximage,boardimage,hintimage,pieceimage,buttonimage,minibtimage,playerimage,ataxxicon
    ataxxicon       =pygame.image.load(resource_path('ataxx.ico'))
    backgroundimage =pygame.image.load(resource_path('background.jpg'))
    infoboximage    =pygame.image.load(resource_path('infobackground.png'))
    boardimage      =pygame.image.load(resource_path('board.png'))
    hintimage[0]    =pygame.image.load(resource_path('green.png'))
    hintimage[1]    =pygame.image.load(resource_path('yellow.png'))
    pieceimage[0][0]=pygame.image.load(resource_path('black.png'))
    pieceimage[0][1]=pygame.image.load(resource_path('tranblack.png'))
    pieceimage[0][2]=pygame.image.load(resource_path('lightblack.png'))
    pieceimage[0][3]=pygame.image.load(resource_path('darkblack.png'))
    pieceimage[1][0]=pygame.image.load(resource_path('white.png'))
    pieceimage[1][1]=pygame.image.load(resource_path('tranwhite.png'))
    pieceimage[1][2]=pygame.image.load(resource_path('lightwhite.png'))
    pieceimage[1][3]=pygame.image.load(resource_path('darkwhite.png'))
    buttonimage[0]  =pygame.image.load(resource_path('up.png'))
    buttonimage[1]  =pygame.image.load(resource_path('down.png'))
    buttonimage[2]  =pygame.image.load(resource_path('grey.png'))
    minibtimage[0]  =pygame.image.load(resource_path('downup.png'))
    minibtimage[1]  =pygame.image.load(resource_path('downdown.png'))
    minibtimage[2]  =pygame.image.load(resource_path('upup.png'))
    minibtimage[3]  =pygame.image.load(resource_path('updown.png'))
    playerimage[0]  =pygame.image.load(resource_path('player.png'))
    playerimage[1]  =pygame.image.load(resource_path('ai.png'))
    playerimage[2]  =pygame.image.load(resource_path('ai0.png'))

pygame.init()
window = pygame.display.set_mode((WIDTH, HIGHT))
loadimages()
alphasur = window.convert_alpha()
pygame.display.set_icon(ataxxicon)
pygame.display.set_caption(CODETITLE)
clock = pygame.time.Clock()
while not quitgame:
    clock.tick(FPS)
    mousepos = getpos()
    if mousepos:
        mouseproc(mousepos[0],mousepos[1])
    else:
        beginstate &= 2;settingstate &= 2;withdrawstate &= 2;giveupstate &= 2;updownstate &= 2
        importstate &= 2;exportstate &= 2;playbackstate &= 2;speedstate &= 2
        if not aiworking and not displayok:
            wantpiece = None
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quitgame = True
        elif event.type == pygame.MOUSEBUTTONDOWN:
            getmouse()
#        elif event.type == pygame.KEYDOWN:
#            getkey()
    if aiworking and not gameover:
        if aidelay:
            aidelay -= 1
        elif aiok:
            makemove()
        elif not aistart:
            aistart = True
            aithread = Thread(target=aiwork)
            aithread.start()
    if displaying:
        if steps < dpstep:
            if dpdelay:
                dpdelay -= 1
            elif dpok:
                makemove()
                dpok = False
                dpdelay = DPDELAY/(1<<dpspeed)
            else:
                tmppiece = (int(importtext[steps][0]),int(importtext[steps][1]))
                wantpiece = (int(importtext[steps][2]),int(importtext[steps][3]))
                dpok = True
                dpdelay = DPDELAY/(1<<dpspeed)
        elif not gameover:
            uptext = '   回放结束'
            displaying = False
            gameover = True
            playerid = 0; beginstate = 0; giveupstate = 2
    procinfo()
    show()
    pygame.display.update()

